﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Manyor.Net
{
    /// <summary>
    /// 字节处理辅助类
    /// </summary>
    public class ByteUtility
    {
        /// <summary>
        /// 生成数据包的头部
        /// </summary>
        /// <param name="commandFiled">命令ID</param>
        /// <param name="StatusField">状态ID</param>
        /// <param name="ExtFiled">扩展</param>
        /// <returns></returns>
        public static byte[] SocketHeader(params int[] values)
        {
            #region
            int commandFiled=0;
            int? StatusField = null; 
            int? ExtFiled = null;
            if (values.Length >0)
            {
                commandFiled = values[0];
            }
            if (values.Length > 1)
            {
                StatusField = values[1];
            }
            if (values.Length > 2)
            {
                ExtFiled = values[2];
            }

            byte[] header = new byte[32];
            byte[] command = ConvertSpecialBytes(BitConverter.GetBytes(commandFiled),8);

            for (int i = 0; i < 8; i++)
            {
                header[i] = command[i];
            }

            if (StatusField.HasValue)
            {
                byte[] status = ConvertSpecialBytes(BitConverter.GetBytes(StatusField.Value), 8);
                for (int i = 8; i < 15; i++)
                {
                    header[i] = status[i-8];
                }
            }

            if (ExtFiled.HasValue)
            {
                byte[] ext = ConvertSpecialBytes(BitConverter.GetBytes(ExtFiled.Value), 16);
                for (int i = 16; i < 31; i++)
                {
                    header[i] = ext[i-16];
                }
            }
            return header;
            #endregion
        }

        /// <summary>
        ///  生成数据包的头部
        /// </summary>
        /// <param name="sh"></param>
        /// <returns></returns>
        public static byte[] SocketHeader(SocketHeader sh)
        {
            return SocketHeader(sh.CommandField, sh.StatuField, sh.ExtField);
        }
        /// <summary>
        /// 将数据头压入到数据包中
        /// </summary>
        /// <param name="sh"></param>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static byte[] PushSockHeaderToBytes(SocketHeader sh, byte[] bytes)
        {
            byte[] header = SocketHeader(sh.CommandField, sh.StatuField, sh.ExtField);
            if (bytes.Length >= header.Length)
            {
                header.CopyTo(bytes, 0);
            }
            return bytes;
        }

        /// <summary>
        /// 将指定的字节数组转换为指定长度，高位补0。
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static byte[] ConvertSpecialBytes(byte[] bytes, int length)
        {
            if (bytes.Length > length)
                throw new Exception("ConvertSpecialBytes 转换失败");
            byte[] bytesCopy = new byte[length];
            for (int i = length - 1; i >= 0; i--)
            {
                if (bytes.Length - 1 > i)
                    bytesCopy[i] = bytes[i];
            }
            return bytesCopy;
        }

        /// <summary>
        /// 合并2个二进制数组
        /// </summary>
        /// <param name="bytes0"></param>
        /// <param name="bytes1"></param>
        /// <returns></returns>
        public static byte[] CombineBytes(byte[] bytes0, byte[] bytes1)
        {
            byte[] bytesCopy = new byte[bytes0.Length + bytes1.Length];
            bytes0.CopyTo(bytesCopy, 0);
            bytes1.CopyTo(bytesCopy, bytes0.Length);
            return bytesCopy;
        }

        /// <summary>
        /// 提取数据包的头
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static SocketHeader ConvertHeader(byte[] bytes)
        {            
            SocketHeader sh = new SocketHeader();
            if (bytes.Length >= NetConfig.HEADER_SIZE)
            {
                sh.CommandField = BitConverter.ToInt16(SubBytes(bytes, 0, 8),0);
                sh.StatuField = BitConverter.ToInt16(SubBytes(bytes, 8, 8), 0);
                sh.ExtField = BitConverter.ToInt16(SubBytes(bytes, 16, 16), 0);
            }
            else
                throw new Exception("header 位数不足！");
            return sh;
        }

        /// <summary>
        /// 从指定的字节数组中提取指定位
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="startIndex"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static byte[] SubBytes(byte[] bytes, int startIndex, int count)
        {
            IList<byte> ls = new List<byte>();
            if (bytes.Length >= startIndex + 1 && bytes.Length >= count)
            {
                for (int i = startIndex; i < bytes.Length; i++)
                {
                    ls.Add(bytes[i]);
                }
            }
            return ls.ToArray();
        }
    }
}
